package com.peza.mines.domain;

import java.util.ArrayList;
import java.util.List;

public class Board {

	
	//private int[][] board;
	
	private Field [][] fields;
	
	private int size;
	
	private boolean exploded;
	
	public Board (int size, int mines){
		this.size = size;
		//board = new int[size][size];
		fields = new Field[size][size];
		populate(createMines(mines));
		labelFields();
	}
	
	
	public Field getField(int y, int x){
		return fields[y][x];
	}
	
	public void setField(int y, int x, FieldClass value){
		fields[y][x].setType(value);
	}
	
	public void updateField(Field field){
		Field oldfield = getFieldById(field.getId());
		System.out.println("Updating field:"+field.toString());
		fields[oldfield.getYpos()][oldfield.getxPos()] = field;
	}
	
	public Field getFieldById(int id) {
		for (int y = 0; y < size; y++){
			for (int x = 0; x < size; x++){
				Field field = fields[y][x];
				if (field.getId() == id){
					return field;
				}
			}
		}
		return null;
	}
	
	public Field[][] getFields() {
		return fields;
	}


	public void setFields(Field[][] fields) {
		this.fields = fields;
	}


	/** puts the board and the mines together **/
	private void populate(List<Integer> mines){

		int counter = 0;
		for (int y = 0; y < size; y++){
			for (int x = 0; x < size; x++){
				if (mines.contains(counter)){
					//board[y][x] = 9;
					fields[y][x] = new Field(counter, x, y, FieldClass.MINE);
				} else {
					//board[y][x] = 0;
					fields[y][x] = new Field(counter, x, y, FieldClass.FREE);
				}
			counter++;
			}
		}
	}
	
	
	/** Returns a list of ints representing minefield IDs **/ 
	private List<Integer> createMines(int mines) {
		int counter = 0;
		List<Integer> fields = new ArrayList<Integer>();
		
		/** get minefields **/
		while (counter < mines){
			int random = getRandom(0, (size*size)-1);
			if (!fields.contains(random)){
				fields.add(random);
				counter++;
			}
		}
		return fields;
	}	

	/** Put number labels on grid fields**/
	private void labelFields(){
		for (int y = 0; y < size; y++){
			for (int x = 0; x < size; x++){
				int counter = 0;
				
				/** check all surrounding fields **/
				/** but do not check minefields **/
				//if (board[y][x] != 9){
				if (fields[y][x].getType() != FieldClass.MINE){	
					for (int offsety = -1; offsety < 2; offsety++){
						for (int offsetx = -1; offsetx < 2; offsetx++ ){
							try {
								int ycoord = y+offsety;
								int xcoord = x+offsetx;
								/** do not check the center field **/
								if (!(y == ycoord && x == xcoord)){
									/** if checked field is a mine */
									if (fields[ycoord][xcoord].getType() == FieldClass.MINE){
										counter++;
									}
								}
							} catch (ArrayIndexOutOfBoundsException e) {
								/** nothing to do here, just move to next iteration **/
							}	
							
						}
					}
				/** set counter as new field value **/	
				fields[y][x].setProx(counter);
				}
			}		
		}
		
	}
	
	
	/** Return a random integer between min and max **/
	private int getRandom(int min, int max){
		Double value = (min + Math.random()*max);
		return (int) Math.round(value);
	}

	
	
	
	
	public boolean isFree(int x, int y){
		
		if (fields[y][x].getType() == FieldClass.FREE){
			return true;
		} else {
			return false;
		}
		
	}
	

	public boolean isExploded() {
		return exploded;
	}


	public void setExploded(boolean eploded) {
		this.exploded = eploded;
	}


	@Override
	public String toString(){
		StringBuffer buffer = new StringBuffer();		
		for (int y = 0; y < size; y++){
			for (int x = 0; x < size; x++) {
				buffer.append("" + fields[y][x].toString() + "\t");
			}
			buffer.append("\n");
		}
		return buffer.toString();
	}


	
	
}
